package missObjects;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Hashtable;
import java.util.List;
import java.util.Scanner;
import java.util.logging.Logger;

import main.LandingPoint;

/**
 * Manage airfields model data list from Rof UNGTP directory
 * 
 * @author Lefuneste
 * 
 */

public class AirfieldsModelList {

	private static Logger LOGGER = Logger.getLogger("RofLogger");
	private static Hashtable<String, String[]> airfieldsModelInfos = new Hashtable<>();

	static {
		LOGGER.getUseParentHandlers();
	}

	/**
	 * Read airfields model data list from Rof UNGTP directory
	 * 
	 * @param UnGTPDirectory
	 *            Directory where lua files are extracted by UNGTP. Has to be
	 *            defined by User with IHM
	 * @return number of Airfields read
	 * @throws IOException
	 */
	public static int ReadFromFile(String UnGTPDirectory) throws IOException {
		Path unGTPPath = Paths.get(UnGTPDirectory);
		String tmpName = null;
		int count = 0;
		String[] tmpinfos;

		try (DirectoryStream<Path> stream = Files.newDirectoryStream(unGTPPath,
				"*.txt")) {
			for (Path file : stream) {
				List<String> lines = Files.readAllLines(file,
						StandardCharsets.ISO_8859_1);
				String fistLine = lines.get(0);
				try (Scanner scanner = new Scanner(fistLine)) {
					scanner.useDelimiter("=");
					if (scanner.hasNext()) {
						// assumes the line has a certain structure
						scanner.next().trim();
						String value = scanner.next().trim();
						if (value.equals("\"CAirfield\"")) {
							tmpinfos = new String[4];
							for (String line : lines) {
								if (line.contains("=")) {
									try (Scanner scanner2 = new Scanner(line)) {
										scanner2.useDelimiter("=");
										String name2 = scanner2.next().trim();
										String value2 = scanner2.next().trim();

										switch (name2) {
										case "object_name":
											tmpName = value2.toLowerCase();
											break;
										case "takeoffDx":
											tmpinfos[LandingPoint.TAKEOFFDX
													.getIndex()] = value2;
											break;
										case "takeoffDz":
											tmpinfos[LandingPoint.TAKEOFFDZ
													.getIndex()] = value2;
											break;
										case "takeoffDoy":
											tmpinfos[LandingPoint.TAKEOFFDOY
													.getIndex()] = value2;
											break;
										}
									}
								}
							}

							airfieldsModelInfos.put(tmpName, tmpinfos);
							LOGGER.fine("Airfield model:" + file.getFileName()
									+ " Read from file");
							count++;
						}
					}
				}
			}

		} catch (Exception e) {
			LOGGER.severe(e.getClass().getName() + ": " + e.getMessage());
			throw (e);
		}
		LOGGER.info(count + " Airfield model read from file");
		return count;
	}

	/**
	 * To Debug purpose
	 */
	public static void print() {
		for (String key : airfieldsModelInfos.keySet()) {
			System.out.println(key + ":" + airfieldsModelInfos.get(key)[0]
					+ "," + airfieldsModelInfos.get(key)[1] + ","
					+ airfieldsModelInfos.get(key)[2] + ","
					+ airfieldsModelInfos.get(key)[3]);
		}
	}

	/**
	 * store the airfield into DB
	 * 
	 * @param connection
	 *            to DB
	 * @throws SQLException
	 */
	public static void storeToDB(Connection con) throws SQLException {
		int count = 0;
		try (Statement stmt = con.createStatement()) {
			String sql = "CREATE TABLE IF NOT EXISTS AIRFIELDDATA"
					+ "(ID INTEGER PRIMARY KEY     AUTOINCREMENT NOT NULL,"
					+ " NAME          		TEXT    NOT NULL,"
					+ " TAKEOFFDX          TEXT    NOT NULL,"
					+ " TAKEOFFDZ          TEXT    NOT NULL,"
					+ " TAKEOFFDOY           TEXT    NOT NULL );";

			stmt.executeUpdate(sql);

			stmt.addBatch("DELETE FROM AIRFIELDDATA;");

			for (String key : airfieldsModelInfos.keySet()) {
				sql = "INSERT INTO AIRFIELDDATA (NAME, TAKEOFFDX, TAKEOFFDZ, TAKEOFFDOY ) VALUES('"
						+ key
						+ "','"
						+ airfieldsModelInfos.get(key)[LandingPoint.TAKEOFFDX
								.getIndex()]
						+ "','"
						+ airfieldsModelInfos.get(key)[LandingPoint.TAKEOFFDZ
								.getIndex()]
						+ "','"
						+ airfieldsModelInfos.get(key)[LandingPoint.TAKEOFFDOY
								.getIndex()] + "');";
				stmt.addBatch(sql);
				count++;
			}
			stmt.executeBatch();
			LOGGER.info(count + " Airfield model stored in DB");

			stmt.close();
		} catch (Exception e) {
			LOGGER.severe(e.getClass().getName() + ": " + e.getMessage());
			throw (e);
		}

	}

	/**
	 * Read whole airfield data from DB
	 * 
	 * @param con
	 *            connection to DB
	 * @throws SQLException
	 */
	public static void readFromDB(Connection con) throws SQLException {

		String[] tmpinfos = null;
		String tmpName = "";
		int count = 0;

		try (Statement stmt = con.createStatement()) {

			String sql = "SELECT * FROM AIRFIELDDATA";
			ResultSet resultSet = stmt.executeQuery(sql);
			while (resultSet.next()) {
				tmpinfos = new String[4];
				tmpName = resultSet.getString("NAME");
				tmpinfos[LandingPoint.TAKEOFFDX.getIndex()] = resultSet
						.getString("TAKEOFFDX");
				tmpinfos[LandingPoint.TAKEOFFDZ.getIndex()] = resultSet
						.getString("TAKEOFFDZ");
				tmpinfos[LandingPoint.TAKEOFFDOY.getIndex()] = resultSet
						.getString("TAKEOFFDOY");
				airfieldsModelInfos.put(tmpName, tmpinfos);
				LOGGER.fine("Airfield:" + tmpName + " Read from DB");
				count++;
			}
			LOGGER.info(count + " Airfield models readed from DB");
			stmt.close();

		} catch (Exception e) {
			LOGGER.severe(e.getClass().getName() + ": " + e.getMessage());
			throw (e);
		}

	}

}
